package de.schule.barnimgymnasium.javafx.fxMediaPlayer;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class JogShuttle implements AutoCloseable, Runnable {

	byte wheel;
	private int speed;
	private final InputStream in;
	Thread run;
	final private List<InputEvent> inputEvents = new ArrayList<InputEvent>();
	Set<JogShuttleListener> jsListener = new HashSet<JogShuttleListener>();

	class InputEvent {
		Date timeval;
		short type;
		short key;
		int value;

		InputEvent(final byte[] bytes) {
			ByteBuffer bb = ByteBuffer.wrap(bytes);
			bb.order(ByteOrder.LITTLE_ENDIAN); // or BIG_ENDIAN
			long seconds = bb.getLong();
			long microseconds = bb.getLong();
			timeval = new Date(seconds + microseconds / 1000);
			type = bb.getShort();
			key = bb.getShort();
			value = bb.getInt();
		}

		public String toString() {
			StringBuffer sb = new StringBuffer();
			sb.append("At ").append(timeval);
			sb.append(" : Type ").append(type);
			sb.append(" Key ").append(key);
			sb.append(" Value ").append(value);
			return sb.toString();
		}
	}

	public JogShuttle(int eventNumber) throws IOException {
		Path shuttlePath = FileSystems.getDefault().getPath(
				FileSystems.getDefault().getSeparator(), "dev", "input",
				"event" + String.valueOf(eventNumber));
		in = Files.newInputStream(shuttlePath, StandardOpenOption.READ);
		Thread t = new Thread(this);
		t.run();
	}

	public void addJogShuttleListener(JogShuttleListener listener) {
		jsListener.add(listener);
	}

	public void removeJogShuttleListener(JogShuttleListener listener) {
		jsListener.remove(listener);
	}

	@Override
	public void run() {
		final int INPUT_EVENT_SIZE = 48;
		byte buf[] = new byte[INPUT_EVENT_SIZE]; // long, long, short, short,
													// int
		int byteCount;
		try {
			do {
				byteCount = in.read(buf);
				if (byteCount != INPUT_EVENT_SIZE)
					continue;
				InputEvent ie = new InputEvent(buf);
				System.out.println(ie);
				if (ie.type == 0) {
					processEvents();
				} else {
					inputEvents.add(ie);
				}

			} while (byteCount >= 0);
		} catch (IOException ex) {

		}
	}

	private void processEvents() {
		boolean speedChanged = false;
		for (InputEvent e : inputEvents) {
			switch (e.type) {
			case 2:
				// Jog + Shuttle
				break;

			case 4:
				// Keys
				break;
			}
		}
		inputEvents.clear();
		for (JogShuttleListener jsl : jsListener) {
			if (speedChanged) {
				jsl.setPlaybackSpeed(speed);
			}
		}
	}

	@Override
	public void close() throws IOException {
		in.close();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// UDEV permission rules
		// KERNEL=="event*", NAME="input/%k", MODE="660", GROUP="input"
		// KERNEL=="js*", NAME="input/%k", MODE="664", GROUP="input"
		try (JogShuttle js = new JogShuttle(13)) {
			JogShuttleDisplay jsDisplay = new JogShuttleDisplay();
			js.addJogShuttleListener(jsDisplay);
			jsDisplay.open();
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class JogShuttleDisplay implements JogShuttleListener {

	@Override
	public void setPlaybackSpeed(int speed) {
		System.out.println("PlaybackSpeed: " + String.valueOf(speed));
	}

	@Override
	public void stepFrames(int frames) {
		System.out.println("Step " + String.valueOf(Math.abs(frames))
				+ " Frames " + ((frames < 0) ? "backward" : "forward"));
	}

	public void open() throws InterruptedException {
		Thread.sleep(10000);
	}

}
